import sys
import socket

from PyQt5.QtWidgets import QMessageBox

from PyQt5.QtWidgets import QApplication

# from UI.MainWindowUI import mainWindowUI
from tcp_logic import TcpLogic
from udp_logic import UdpLogic


class mainWindow(TcpLogic, UdpLogic):
    def __init__(self, num):
        super().__init__(num)
        self.another = None
        self.num = num
        self.link = False

        self.connect()
        self.click_get_ip()

    def connect(self):
        """
        控制信号-槽的设置
        :param:
        :return: None
        """
        self.signal_write_msg.connect(self.write_msg)
        self.pushButton_get_ip.clicked.connect(self.click_get_ip)
        self.pushButton_else.clicked.connect(self.another_window)
        self.comboBox_tcp.currentIndexChanged.connect(self.combobox_change)
        self.pushButton_link.clicked.connect(self.click_link)
        self.pushButton_unlink.clicked.connect(self.click_unlink)
        self.pushButton_send.clicked.connect(self.send_msg)

        self.pushButton_exit.clicked.connect(self.close)

    def send_msg(self):
        """
        pushButton_send的信号槽

        """
        if (
            self.comboBox_tcp.currentIndex() == 0
            or self.comboBox_tcp.currentIndex() == 1
        ):
            self.tcp_send()

        elif (
            self.comboBox_tcp.currentIndex() == 2
            or self.comboBox_tcp.currentIndex() == 3
        ):
            self.udp_send()

    def write_msg(self, msg):
        # signal_write_msg信号会触发这个函数
        """
        功能函数，向接收区写入数据的方法
        信号-槽触发
        tip：PyQt程序的子线程中，直接向主线程的界面传输字符是不符合安全原则的
        :return: None
        """
        self.textEdit_recive.append(msg)

    def click_get_ip(self):
        """
        获取本地主机ip
        """
        # 获取本机ip
        self.lineEdit_local_ip.clear()
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        try:
            s.connect(("8.8.8.8", 80))
            my_addr = s.getsockname()[0]
            # print(my_addr)
            self.lineEdit_local_ip.setText(str(my_addr))
        except Exception as e:
            print("无法获取本地ip ", e)
            # 若无法连接互联网使用，会调用以下方法
            try:
                my_addr = socket.gethostbyname(socket.gethostname())
                self.lineEdit_local_ip.setText(str(my_addr))
            except Exception as ret_e:
                self.signal_write_msg.emit("无法获取ip，请连接网络！\n")
        finally:
            s.close()

    def click_link(self):
        """
        pushButton_link控制点击触发的槽
        :return: None
        """
        # 连接时根据选择触发功能函数
        if self.comboBox_tcp.currentIndex() == 0:
            self.tcp_server_start()

        elif self.comboBox_tcp.currentIndex() == 1:
            self.tcp_client_start()
        elif self.comboBox_tcp.currentIndex() == 2:
            self.udp_server_start()
        elif self.comboBox_tcp.currentIndex() == 3:
            self.udp_client_start()
        # if self.comboBox_tcp.currentIndex() == 4:
        #     self.web_server_start()
        self.link = True
        self.pushButton_unlink.setEnabled(True)
        self.pushButton_link.setEnabled(False)

    def click_unlink(self):
        """
        pushButton_link控制点击触发的槽
        :return: None
        """
        self.close_all()
        self.link = False
        self.pushButton_unlink.setEnabled(False)
        self.pushButton_link.setEnabled(True)
        self.textEdit_recive.append("已断开网络\n")

    def another_window(self):
        """
        开启另一个新的窗口方法
        :return:
        """
        # 弹出一个消息框，提示开启了一个新的窗口
        QMessageBox.warning(
            self,
            "TCP/UDP网络测试助手",
            "已经开启了新的TCP/UDP网络测试助手！",
            QMessageBox.Yes,
        )
        # 计数， 开启了几个窗口
        self.num = self.num + 1
        # 开启新的窗口
        self.another = mainWindow(self.num)
        self.another.show()

    def combobox_change(self):
        if (
            self.comboBox_tcp.currentIndex() == 0
            or self.comboBox_tcp.currentIndex() == 2
        ):
            self.label_sendto.hide()

            self.lineEdit_ip_send.hide()

            self.label_port.setText("端口号：")

        elif (
            self.comboBox_tcp.currentIndex() == 1
            or self.comboBox_tcp.currentIndex() == 3
        ):
            self.label_sendto.show()
            self.lineEdit_ip_send.show()

            self.label_port.setText("目标端口：")

    def close_all(self):
        """
        功能函数，关闭网络连接的方法
        :return:
        """
        # 连接时根据用户选择的功能调用函数
        if (
            self.comboBox_tcp.currentIndex() == 0
            or self.comboBox_tcp.currentIndex() == 1
        ):
            self.tcp_close()
        elif (
            self.comboBox_tcp.currentIndex() == 2
            or self.comboBox_tcp.currentIndex() == 3
        ):
            self.udp_close()
        # if self.comboBox_tcp.currentIndex() == 4:
        #     self.web_close()
        self.reset()

    def reset(self):
        """
        功能函数，将按钮重置为初始状态
        :return:None
        """
        self.link = False
        self.client_socket_list = list()
        self.pushButton_unlink.setEnabled(False)
        self.pushButton_link.setEnabled(True)


if __name__ == "__main__":

    app = QApplication(sys.argv)
    ex = mainWindow(1)
    sys.exit(app.exec_())
